home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / as / sprite / as.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-28  |  7.6 KB  |  275 lines

  1. /* as.c - GAS main program.
  2.    Copyright (C) 1987 Free Software Foundation, Inc.
  3.  
  4. This file is part of GAS, the GNU Assembler.
  5.  
  6. GAS is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GAS is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GAS; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /*
  21.  * Main program for AS; a 32-bit assembler of GNU.
  22.  * Understands command arguments.
  23.  * Has a few routines that don't fit in other modules because they
  24.  * are shared.
  25.  *
  26.  *
  27.  *            bugs
  28.  *
  29.  * : initialisers
  30.  *    Since no-one else says they will support them in future: I
  31.  * don't support them now.
  32.  *
  33.  */
  34.  
  35. #define COMMON
  36. #include "as.h"
  37. #include "struc-symbol.h"
  38. #include "write.h"
  39.         /* Warning!  This may have some slightly strange side effects
  40.            if you try to compile two or more assemblers in the same
  41.            directory!
  42.          */
  43.  
  44. static char * gdb_symbol_file_name;
  45. int had_warnings;
  46. char *myname;        /* argv[0] */
  47. extern char version_string[];
  48.  
  49. main(argc,argv)
  50. int    argc;
  51. char    **argv;
  52. {
  53.     int    work_argc;    /* variable copy of argc */
  54.     char    **work_argv;    /* variable copy of argv */
  55.     char    *arg;        /* an arg to program */
  56.     char    a;        /* an arg flag (after -) */
  57.  
  58.     char    *stralloc();    /* Make a (safe) copy of a string. */
  59.     long int gdb_begin();
  60.     void    symbol_begin();
  61.     void    read_begin();
  62.     void    write_object_file();
  63.  
  64.     myname=argv[0];
  65.     bzero (flagseen, sizeof(flagseen)); /* aint seen nothing yet */
  66.     out_file_name    = "a.out";    /* default .o file */
  67.     symbol_begin();        /* symbols.c */
  68.     subsegs_begin();        /* subsegs.c */
  69.     read_begin();            /* read.c */
  70.     md_begin();            /* MACHINE.c */
  71.     input_scrub_begin();        /* input_scrub.c */
  72.     gdb_symbol_file_name = 0;
  73.     /*
  74.      * Parse arguments, but we are only interested in flags.
  75.      * When we find a flag, we process it then make it's argv[] NULL.
  76.      * This helps any future argv[] scanners avoid what we processed.
  77.      * Since it is easy to do here we interpret the special arg "-"
  78.      * to mean "use stdin" and we set that argv[] pointing to "".
  79.      * After we have munged argv[], the only things left are source file
  80.      * name(s) and ""(s) denoting stdin. These file names are used
  81.      * (perhaps more than once) later.
  82.      */
  83.     work_argc = argc-1;        /* don't count argv[0] */
  84.     work_argv = argv+1;        /* skip argv[0] */
  85.     for (;work_argc--;work_argv++) {
  86.         arg = * work_argv;    /* work_argv points to this argument */
  87.  
  88.         if (*arg!='-')        /* Filename. We need it later. */
  89.             continue;    /* Keep scanning args looking for flags. */
  90.         if (arg[1] == '-' && arg[2] == 0) {
  91.             /* "--" as an argument means read STDIN */
  92.             /* on this scan, we don't want to think about filenames */
  93.             * work_argv = "";    /* Code that means 'use stdin'. */
  94.             continue;
  95.         }
  96.                 /* This better be a switch. */
  97.         arg ++;        /* -> letter. */
  98.  
  99.         while (a = * arg)  {/* scan all the 1-char flags */
  100.             arg ++;    /* arg -> after letter. */
  101.             a &= 0x7F;    /* ascii only please */
  102.             if (flagseen[a])
  103.                 as_warn("%s: Flag option -%c has already been seen!",myname,a);
  104.             flagseen[a] = TRUE;
  105.             switch (a) {
  106.             case 'f':
  107.                 break;    /* -f means fast - no need for "app" preprocessor. */
  108.  
  109.             case 'D':
  110.                 /* DEBUG is implemented: it debugs different */
  111.                 /* things to other people's assemblers. */
  112.                 break;
  113.  
  114.             case 'G':    /* GNU AS switch: include gdbsyms. */
  115.                 if (*arg)    /* Rest of argument is file-name. */
  116.                     gdb_symbol_file_name = stralloc (arg);
  117.                 else if (work_argc) {    /* Next argument is file-name. */
  118.                     work_argc --;
  119.                     * work_argv = NULL; /* Not a source file-name. */
  120.                     gdb_symbol_file_name = * ++ work_argv;
  121.                 } else
  122.                     as_warn( "%s: I expected a filename after -G",myname);
  123.                 arg = "";    /* Finished with this arg. */
  124.                 break;
  125.  
  126.  
  127. #ifndef WORKING_DOT_WORD
  128.             case 'k':
  129.                 break;
  130. #endif
  131.  
  132.             case 'L': /* -L means keep L* symbols */
  133.                 break;
  134.  
  135.             case 'o':
  136.                 if (*arg)    /* Rest of argument is object file-name. */
  137.                     out_file_name = stralloc (arg);
  138.                 else if (work_argc) {    /* Want next arg for a file-name. */
  139.                     * work_argv = NULL; /* This is not a file-name. */
  140.                     work_argc--;
  141.                     out_file_name = * ++ work_argv;
  142.                 } else
  143.                     as_warn("%s: I expected a filename after -o. \"%s\" assumed.",myname,out_file_name);
  144.                 arg = "";    /* Finished with this arg. */
  145.                 break;
  146.  
  147.             case 'R':
  148.                 /* -R means put data into text segment */
  149.                 break;
  150.  
  151.             case 'v':
  152. #ifdef    VMS
  153.                 {
  154.                 extern char *compiler_version_string;
  155.                 compiler_version_string = arg;
  156.                 }
  157. #else /* not VMS */
  158.                 fprintf(stderr,version_string);
  159.                 if(*arg && strcmp(arg,"ersion"))
  160.                     as_warn("Unknown -v option ignored");
  161. #endif
  162.                 while(*arg) arg++;    /* Skip the rest */
  163.                 break;
  164.  
  165.             case 'W':
  166.                 /* -W means don't warn about things */
  167.                 break;
  168.  
  169.             default:
  170.                 --arg;
  171.                 if(md_parse_option(&arg,&work_argc,&work_argv)==0)
  172.                     as_warn("%s: I don't understand '%c' flag!",myname,a);
  173.                 if(arg && *arg)
  174.                     arg++;
  175.                 break;
  176.             }
  177.         }
  178.         /*
  179.          * We have just processed a "-..." arg, which was not a
  180.          * file-name. Smash it so the
  181.          * things that look for filenames won't ever see it.
  182.          *
  183.          * Whatever work_argv points to, it has already been used
  184.          * as part of a flag, so DON'T re-use it as a filename.
  185.          */
  186.         *work_argv = NULL; /* NULL means 'not a file-name' */
  187.     }
  188.     if (gdb_begin(gdb_symbol_file_name) == 0)
  189.         flagseen ['G'] = 0;    /* Don't do any gdbsym stuff. */
  190.     /* Here with flags set up in flagseen[]. */
  191.     perform_an_assembly_pass(argc,argv); /* Assemble it. */
  192.  
  193.     if (had_warnings) {
  194.         fprintf(stderr, "NO OBJECT FILE CREATED!\n"); 
  195.         exit(1);
  196.     }
  197.     if (seen_at_least_1_file())
  198.         write_object_file();/* relax() addresses then emit object file */
  199.     input_scrub_end();
  200.     md_end();            /* MACHINE.c */
  201. #ifndef    VMS
  202.     exit(0);            /* WIN */
  203. #else    /* VMS */
  204.     exit(1);            /* WIN */
  205. #endif    /* VMS */
  206. }
  207.  
  208.  
  209. /*            perform_an_assembly_pass()
  210.  *
  211.  * Here to attempt 1 pass over each input file.
  212.  * We scan argv[*] looking for filenames or exactly "" which is
  213.  * shorthand for stdin. Any argv that is NULL is not a file-name.
  214.  * We set need_pass_2 TRUE if, after this, we still have unresolved
  215.  * expressions of the form (unknown value)+-(unknown value).
  216.  *
  217.  * Note the un*x semantics: there is only 1 logical input file, but it
  218.  * may be a catenation of many 'physical' input files.
  219.  */
  220. perform_an_assembly_pass (argc, argv)
  221. int    argc;
  222. char **    argv;
  223. {
  224.     char *    buffer;        /* Where each bufferful of lines will start. */
  225.     void    read_a_source_file();
  226.     int saw_a_file = 0;
  227.  
  228.     text_fix_root        = NULL;
  229.     data_fix_root        = NULL;
  230.     need_pass_2        = FALSE;
  231.  
  232.     argv++;            /* skip argv[0] */
  233.     argc--;            /* skip argv[0] */
  234.     while (argc--) {
  235.         if (*argv) {        /* Is it a file-name argument? */
  236.             /* argv -> "" if stdin desired, else -> filename */
  237.             if (buffer = input_scrub_new_file (*argv) ) {
  238.                 saw_a_file++;
  239.                 read_a_source_file(buffer);
  240.             }
  241.         }
  242.         argv++;            /* completed that argv */
  243.     }
  244.     if(!saw_a_file)
  245.         if(buffer = input_scrub_new_file("") )
  246.             read_a_source_file(buffer);
  247. }
  248.  
  249. /*
  250.  *            stralloc()
  251.  *
  252.  * Allocate memory for a new copy of a string. Copy the string.
  253.  * Return the address of the new string. Die if there is any error.
  254.  */
  255.  
  256. char *
  257. stralloc (str)
  258. char *    str;
  259. {
  260.     register char *    retval;
  261.     register long int    len;
  262.  
  263.     len = strlen (str) + 1;
  264.     retval = xmalloc (len);
  265.     (void)strcpy (retval, str);
  266.     return (retval);
  267. }
  268.  
  269. lose()
  270. {
  271.     as_fatal( "%s: 2nd pass not implemented - get your code from random(3)",myname );
  272. }
  273.  
  274. /* end: as.c */
  275.